﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using Golden.Gegerla.Service.Upload.ServiceContract;
using Golden.Gegerla.Service.Upload.DataContract;
using System.IO;
using System.Web;
using System.Web.Caching;

namespace Golden.Gegerla.Service.Upload
{
    /// <summary>
    /// Upload Service
    /// Upload's multiple Files with using chunks
    /// </summary>
    public class UploadService : IUploadService
    {
        /// <summary>
        /// Upload Sessions Cache
        /// </summary>
        private SessionCache<UploadSession> UploadSessionCache { get; set; }
        /// <summary>
        /// Upload File Sessions Cache
        /// </summary>
        private SessionCache<UploadFileSession> UploadFileSessionCache { get; set; } 

        /// <summary>
        /// Create an Instance of the Service
        /// </summary>
        public UploadService()
        {
            this.UploadSessionCache = new SessionCache<UploadSession>();
            this.UploadFileSessionCache = new SessionCache<UploadFileSession>();
        }

        /// <summary>
        /// Create a new Upload Session
        /// </summary>
        /// <returns>Returns an Upload Session object</returns>
        public UploadSession OpenUploadSession()
        {
            UploadSession uploadSession = new UploadSession()
            {
                Token = Guid.NewGuid(),
                State = UploadState.Created
            };

            this.UploadSessionCache.Add(uploadSession);

            return uploadSession;
        }

        /// <summary>
        /// Create a new File Upload Session
        /// </summary>
        /// <param name="uploadSession">Associated Upload Session</param>
        /// <param name="fileInfo">File Information Properties</param>
        /// <returns>Returns an Upload File Session object</returns>
        public UploadFileSession OpenFileUploadSession(UploadSession uploadSession, FileInfo fileInfo)
        {
            if (uploadSession == null)
                throw new ArgumentNullException("uploadSession");
            if (fileInfo == null)
                throw new ArgumentNullException("fileInfo");

            UploadFileSession uploadFileSession = new UploadFileSession()
            {
                Token = Guid.NewGuid(),
                FileName = fileInfo.Name,
                FileSize = fileInfo.Length,
                State = UploadState.Created
            };

            this.UploadFileSessionCache.Add(uploadFileSession);

            return uploadFileSession;
        }

        /// <summary>
        /// Upload a Chunk of Data
        /// </summary>
        /// <param name="chunkData">Chunk Data as binary array</param>
        /// <param name="startPosition">Start Position of the Chunk Data</param>
        /// <param name="length">Length of Chunk Data</param>
        /// <param name="uploadFileSession">Associated Upload File Session</param>
        public void UploadChunk(byte[] chunkData, UploadFileSession uploadFileSession)
        {
            if (chunkData == null)
                throw new ArgumentNullException("chunkData");
            if (uploadFileSession == null)
                throw new ArgumentNullException("uploadFileSession");

            throw new NotImplementedException();
        }

        /// <summary>
        /// Close a File Upload Session
        /// </summary>
        /// <param name="fileUploadSession">File Upload Session to be closed</param>
        public void CloseFileUploadSession(UploadFileSession fileUploadSession)
        {
            if (fileUploadSession == null)
                throw new ArgumentNullException("fileUploadSession");

            this.UploadFileSessionCache.Remove(fileUploadSession);
        }

        /// <summary>
        /// Close Upload Session
        /// </summary>
        /// <param name="uploadSession">Upload Session to be closed</param>
        public void CloseUploadSession(UploadSession uploadSession)
        {
            if (uploadSession == null)
                throw new ArgumentNullException("uploadSession");

            this.UploadSessionCache.Remove(uploadSession);
        }
    }
}
